package com.kaede.game.config;

import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.stereotype.Component;

import com.kaede.game.anotation.GameHandlerMapping;
import com.kaede.game.anotation.GameController;
import org.springframework.util.StringUtils;

@Component
public class HandlerRegister implements BeanPostProcessor {

	private static final String TAG = "HandlerRegister";

	protected Logger logger = LoggerFactory.getLogger(getClass());

	private Map<String, HandlerWrapper> gameHandlerWrapperMap = new HashMap<>();

	@Override
	public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
		Class<? extends Object> beanClazz = bean.getClass();
		GameController gameController = beanClazz.getAnnotation(GameController.class);
		if(gameController != null) {
			String baseUrl = gameController.value();
			boolean baseUrlIsEmpty = false;
			if(StringUtils.isEmpty(baseUrl)){
				baseUrl = "";
				baseUrlIsEmpty = true;
			}else if(!baseUrl.startsWith("/")){
				baseUrl = "/" + baseUrl;
			}
			Method[] declaredMethods = beanClazz.getDeclaredMethods();
			for (Method method : declaredMethods) {
				GameHandlerMapping gameHandlerMapping = method.getAnnotation(GameHandlerMapping.class);
				if(gameHandlerMapping != null) {
					StringBuffer handerUrlBuilder = new StringBuffer();
					String methodUrl = gameHandlerMapping.value();
					if(StringUtils.isEmpty(methodUrl)){
						if(baseUrlIsEmpty){
							methodUrl = "/";
						}else {
							methodUrl = "";
						}
					}else if(!methodUrl.startsWith("/")){
						methodUrl = "/" + methodUrl;
					}
					handerUrlBuilder.append(baseUrl).append(methodUrl);
					String handerUrl = handerUrlBuilder.toString();
					HandlerWrapper oldHanderWrapper = gameHandlerWrapperMap.get(handerUrl);
					if(oldHanderWrapper != null){
						logger.error("hander is exist! handerUrl:" + handerUrl );
						logger.error("oldHander:" + oldHanderWrapper.getBean().getClass().getSimpleName() + ":" + oldHanderWrapper.getMethod().getName() );
						logger.error("newHander:" + bean.getClass().getSimpleName() + ":" + method.getName() );
					}
					HandlerWrapper handlerWrapper = new HandlerWrapper(method, bean);
					gameHandlerWrapperMap.put(handerUrl, handlerWrapper);
				}
			}
		}
		return BeanPostProcessor.super.postProcessAfterInitialization(bean, beanName);
	}

	public Map<String, HandlerWrapper> getGameHandlerWrapperMap() {
		return gameHandlerWrapperMap;
	}

	public void setGameHandlerWrapperMap(Map<String, HandlerWrapper> gameHandlerWrapperMap) {
		this.gameHandlerWrapperMap = gameHandlerWrapperMap;
	}
}
